package com.share.device.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.device.domain.Cabinet;
import com.share.device.domain.Station;
import com.share.device.domain.StationLocation;
import com.share.device.domain.StationVo;
import com.share.device.service.ICabinetService;
import com.share.device.service.IDeviceService;
import com.share.device.service.IStationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 滴滴滴
 * @CreateTime: 2025-03-29
 * @Description:
 * @Version: 1.0
 */
@Service
@Slf4j
@SuppressWarnings({ "unchecked", "rawtypes"})
//注解用于抑制编译器对未检查类型转换（unchecked）和原始类型（rawtypes）的警告，常用于处理泛型类型擦除时的类型安全提示。
//该代码为编译器注解，无实际运行时逻辑
public class DeviceServiceImpl implements IDeviceService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IStationService stationService;
    @Autowired
    private ICabinetService cabinetService;

    @Override
    public List<StationVo> nearbyStation(String latitude, String longitude) {
        //确定中心点
        //经度 和 纬度
        GeoJsonPoint geoJsonPoint =
                new GeoJsonPoint(Double.parseDouble(longitude), Double.parseDouble(latitude));

        //设置查询半径，比如查询50km。   Metrics.KILOMETERS是单位
        Distance simpleDistance = new Distance(50, Metrics.KILOMETERS);
        //画一个圆圈    第一个值是中心位置，第二个值是半径
        Circle circle = new Circle(geoJsonPoint,simpleDistance);

        //查询MongDB数据.
        Query query = new Query(Criteria.where("location").withinSphere(circle));
        List<StationLocation> list = mongoTemplate.find(query, StationLocation.class);
        if (CollectionUtils.isEmpty(list))
            return null;
        //查询其他需要的数据，进行封装
        //组装数据 TODO 这里stream流知识点已经忘记，以及下面的知识点都需要复习
        List<Long> stationIdList =list.stream().map(StationLocation::getStationId).collect(Collectors.toList());

        //根据所有站点id获取对应站点数据 如：in(1,2,3)
        LambdaQueryWrapper<Station> wrapper = new LambdaQueryWrapper();
        wrapper.in(Station :: getId,stationIdList);
        List<Station> stationList = stationService.list(wrapper);

        /*等同于上面3行
        * List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>()
        *       .in(Station::getId, stationIdList).isNotNull(Station::getCabinetId));
        * */

        // List<Station> --   List<StationVo>
        List<StationVo> stationVoList = new ArrayList<>();

        //遍历
        stationList.forEach(station -> {
            //Station -- StationVo
            StationVo stationVo = new StationVo();
            BeanUtils.copyProperties(station,stationVo);

            // 获取柜机信息
            Long cabinetId = station.getCabinetId();
            Cabinet cabinet = cabinetService.getById(cabinetId);
            //可用充电宝数量大于0，可借用
            if(cabinet.getAvailableNum() > 0) {
                stationVo.setIsUsable("1");
            } else {
                stationVo.setIsUsable("0");
            }
            // 获取空闲插槽数量大于0，可归还
            if (cabinet.getFreeSlots() > 0) {
                stationVo.setIsReturn("1");
            } else {
                stationVo.setIsReturn("0");
            }

            stationVoList.add(stationVo);
        });

        return stationVoList;
    }
}
